#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File Name: fix_media_time.py
# Author: bobo
# Created Time: 20250408
"""
修正照片或视频的exif时间信息
Usage:
    fix_media_time.py [-f <files>...] [--path=<path>]
    fix_media_time.py (-h | --help)
    fix_media_time.py (-v | --version)

Options:
    -h --help  显示帮助信息
    -v  --version  显示版本信息
    <files> 要处理的文件，可以是多个
    --path=<path>  要处理的目录
"""

import glob
import os
import re
from datetime import datetime
from docopt import docopt
import exiftool

# EXT = "*.[jmr][pmk][gp4v]"
PHOTO_SUFFIX = ["*.jpg", "*.jpeg"]
VIDEO_SUFFIX = ["*.mp4"]
NA = "N/A"
# EXT = ["*.mp4"]


def read_exif_time(file_path):
    with exiftool.ExifToolHelper() as et:
        metadata = et.get_metadata(file_path)[0]
        # print(metadata)
        # 提取常用时间标签
        _, ext = os.path.splitext(file_path)

        time_tags = {}
        if "*" + ext in PHOTO_SUFFIX:
            time_tags = {
                # "DateTimeOriginal": metadata.get("EXIF:DateTimeOriginal", NA),
                "CreateDate": metadata.get("EXIF:CreateDate", NA),
                # "ModifyDate": metadata.get("EXIF:ModifyDate", NA),
                # "FileModifyDate": metadata.get("File:FileModifyDate", NA),
                # "TrackCreateDate": metadata.get("QuickTime:TrackCreateDate", NA),
            }
        elif "*" + ext in VIDEO_SUFFIX:
            time_tags = {
                "CreateDate": metadata.get("EXIF:CreateDate", NA),
                # "ModifyDate": metadata.get("EXIF:ModifyDate", NA),
                # "FileModifyDate": metadata.get("File:FileModifyDate", NA),
                # "TrackCreateDate": metadata.get("QuickTime:TrackCreateDate", NA),
                "MediaCreateDate": metadata.get("QuickTime:MediaCreateDate", NA),
            }
        return time_tags


def modify_exif_time(file_path, new_time):
    new_tags = None
    _, ext = os.path.splitext(file_path)
    if "*" + ext in PHOTO_SUFFIX:
        new_tags = {
            "CreateDate": new_time,
        }
    elif "*" + ext in VIDEO_SUFFIX:
        new_tags = {
            "CreateDate": new_time,
            "MediaCreateDate": new_time,
        }

    if not new_tags:
        return None

    with exiftool.ExifToolHelper() as et:
        print("更新：")
        # et.set_tags( ["rose.jpg", "skyblue.png"], tags={"DateTimeOriginal": now}, params=["-P", "-overwrite_original"])
        et.set_tags(
            [file_path],
            tags=new_tags,
            # params=["-P", "-overwrite_original"]
        )
        # et.execute(*args, file_path)
        # et.execute_json(*args)


def parse_time_from_file_name(file_name):
    # 尝试匹配微信导出文件名中时间戳格式
    timestamp_match = re.search(r"(\d{10,13})", file_name)
    if timestamp_match:
        timestamp = timestamp_match.group(1)
        timestamp = int(timestamp.ljust(13, "0"))  # 补齐到13位
        dt = datetime.fromtimestamp(timestamp / 1000)  # 解析时间戳
        return dt.strftime("%Y-%m-%d %H:%M:%S")

    # 尝试匹配日期时间格式
    datetime_match = re.search(r"(\d{8}_\d{6})", file_name)
    if datetime_match:
        datetime_str = datetime_match.group(1)
        dt = datetime.strptime(datetime_str, "%Y%m%d_%H%M%S")
        return dt.strftime("%Y-%m-%d %H:%M:%S")

    return None


def fix_file(file_name):
    print(f"处理文件{file_name}")

    meta_time = read_exif_time(file_name)
    print(f"{file_name} exif信息：{meta_time}")
    if "MediaCreateDate" in meta_time:  # 视频文件
        # exif中有时间信息，不操作,退出
        if meta_time.get("MediaCreateDate", None) != NA:
            return None
    else:  # 照片文件
        if meta_time.get("CreateDate", None) != NA:  # exif中有时间信息，不操作，退出
            return None

    # 尝试解析文件名，获取时间，填写到exif中
    new_time = parse_time_from_file_name(file_name)
    if new_time:
        print(f"{file_name} 更新时间：{new_time}")
        modify_exif_time(file_name, new_time)
    return None


def get_file_list_by_suffix(path, suffixs, recursive=False):
    """根据给定后缀名返回指定目录下匹配的文件

    Args:
        path (string): 指定目录
        recursive (bool): 是否遍历子目录

    Raises:
        Exception: None

    return: 返回匹配的文件列表
    """
    if os.path.isdir(path):
        # f = os.path.join(glob.escape(path), "**")
        # print("Dir:", f)
        match_lst = []
        for ext in suffixs:
            f = os.path.join(glob.escape(path), "**", ext)
            match_lst.extend(
                glob.glob(f, recursive=recursive)
            )  # 如果使用iglob反回为生成器，可以节省内存
        print(f"匹配文件：{len(match_lst)}")
        return match_lst
    else:
        return []


if __name__ == "__main__":
    arguments = docopt(__doc__, version="fix_media_time V1.0")

    if infiles := arguments.get("<files>"):
        print(f"输入文件：{len(infiles)}")
        for f in infiles:
            fix_file(f)
    elif path := arguments.get("--path"):
        print(f"路径：{path}")
        file_lst = get_file_list_by_suffix(path, PHOTO_SUFFIX + VIDEO_SUFFIX, True)
        for f in file_lst:
            fix_file(f)
            # break
    else:
        print(__doc__)
        exit()
